package com.uinnova.product.eam.workable.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.uinnova.product.eam.workable.util.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Component("approvalTaskListener")
public class ApprovalTaskListener implements ExecutionListener {
    @Autowired
    private RuntimeService runtimeService;

    @Value("${approval.task.url}")
    private String approvalTaskUrl;

    @Value("${batch.modify.workbench.task}")
    private String batchModifyStatusUrl;

    @Autowired
    private transient HistoryService historyService;


    @Resource
    private HttpUtil httpUtil;
    @Override
    public void notify(DelegateExecution execution) {
        Map<String, Object> wholeVariables = execution.getVariables();
        String processInstanceId = execution.getProcessInstanceId();
        FlowElement currentFlowElement = execution.getCurrentFlowElement();
        String documentation = currentFlowElement.getDocumentation();

        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(execution.getProcessInstanceId())
                .singleResult();
        System.out.println(historicProcessInstance);
        log.info("流程实例id:{}",historicProcessInstance.getId());
        //获取历史任务
        List<HistoricTaskInstance> historicTaskInstanceList = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(historicProcessInstance.getId())
                .orderByHistoricTaskInstanceEndTime()
                .asc()
                .list();

        //上一任务
        HistoricTaskInstance h =null;
        for (HistoricTaskInstance historicTaskInstance : historicTaskInstanceList) {
            if(historicTaskInstance.getEndTime()!=null&&historicTaskInstance.getDeleteReason() ==null){
                h= historicTaskInstance;
                break;
            }
        }
        if(h==null){
            h = historicTaskInstanceList.get(0);
        }

        log.info("上一任务：{}", JSONObject.valueToString(h));
        List<HistoricVariableInstance> historicVariableInstanceList =  historyService.createHistoricVariableInstanceQuery()
                .processInstanceId(historicProcessInstance.getId())
                .taskId(h.getId()).list();
        //获取上一个节点执行结果
        Map<String, Object> variables = historicVariableInstanceList.stream()
                .filter(v -> !StringUtils.isEmpty(v.getVariableName()))
                .filter(v -> v.getValue() != null)
                .collect(Collectors.toMap(HistoricVariableInstance::getVariableName, HistoricVariableInstance::getValue));
        log.info("变量：{}", JSONObject.valueToString(variables));
        //会签节点
        Object finalResult = variables.get("goOut");
        if (finalResult == null) {
            //单节点
            finalResult = variables.get("pass");
        }
        Object childVariable = variables.get("childVariable");
        String processDefinitionId = historicProcessInstance.getProcessDefinitionKey();

        HistoricProcessInstance hi = historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(execution.getProcessInstanceId())
                .singleResult();
        String startUserId = hi.getStartUserId();
        log.info("流程发起人[startUserId:{}]", startUserId);
        if ("process_end".equals(documentation)||StringUtils.isEmpty(childVariable)) {
            changePlanDiagramStatus(finalResult, historicProcessInstance.getBusinessKey(), processDefinitionId, false, wholeVariables, processInstanceId, startUserId);
        } else {
            com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(childVariable.toString());
            changePlanDiagramStatus(finalResult, jsonObject.getString("childBusinessKey"), processDefinitionId, true, wholeVariables, processInstanceId, startUserId);
        }
    }

    private String changePlanDiagramStatus(Object finalResult,String businessKey,String processDefinitionId,boolean childTask,Map<String, Object> variables,String processInstanceId, String startUserId) {
        String flag = "";
        if (finalResult.toString().equals("pass")) {
            flag = "pass";
        } else if (finalResult.toString().equals("cancel")) {
            flag = "cancel";
        } else if (finalResult.toString().equals("noAgree")) {
            flag = "noAgree";
        }  else if (finalResult.toString().equals("recall")) {
            flag = "recall";
        }else{
            flag = "noPass";
        }
        log.info("变更视图或者方案的状态开始");

        //todo 这个路径需要添加到白名单
        String[] split = processDefinitionId.split(":");
        String splitProcessDefinitionId = split[0];

        String url = approvalTaskUrl+"?approval="+flag+"&defKey="+splitProcessDefinitionId
                +"&businessKey="+businessKey+"&childTask="+childTask+"&startUserLoginCode="+startUserId;
        httpUtil.get(url,Object.class);
        log.info("变更视图或者方案的状态结束");

        Object childVariableList = variables.get("childVariableList");
        Object curTaskId = "";
        if (variables.get("curTaskId") != null) {
            curTaskId = variables.get("curTaskId").toString();
        }
        if ("cancel".equals(flag) && childVariableList != null) {
            JSONArray childVariableArray = JSON.parseArray(childVariableList.toString());
            for (int i = 0; i < childVariableArray.size(); i++) {
                String string = childVariableArray.getString(i);
                com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(string);
                String childBusinessKey = jsonObject.getString("childBusinessKey");
                if(org.apache.commons.lang3.StringUtils.isNotBlank(childBusinessKey)){
                    log.info("存在子流程，将工作台子流程代办一起取消");
                    String cancelChildUrl = batchModifyStatusUrl + "?processInstanceId=" + processInstanceId + "&businessKey=" + childBusinessKey + "&curTaskId=" + curTaskId;
                    httpUtil.get(cancelChildUrl, Boolean.class);
                }
            }
        }
        log.info("工作台子流程代办删除成功");
        return "success";
    }
}
